package com.ajavaer.framework.core.web.controller;

import com.ajavaer.framework.common.message.Message;
import com.ajavaer.framework.common.message.PageMessage;
import com.ajavaer.framework.common.tools.GenericsTools;
import com.ajavaer.framework.common.tools.ObjectTools;
import com.ajavaer.framework.common.tools.StringTools;
import com.ajavaer.framework.common.type.TimeFormat;
import com.ajavaer.framework.core.orm.po.Po;
import com.ajavaer.framework.core.orm.service.BaseService;
import com.ajavaer.framework.core.request.PagingRequest;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public abstract class OrmController<T, ID extends Serializable> extends BaseController implements CallBackController {

    /**
     * 根据id返回对象
     *
     * @param id
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/get/{id}", method = RequestMethod.GET)
    public Message<T> get(@PathVariable ID id) {
        return Message.successResult(getBaseService().getById(id));
    }


    /**
     * 根据id列表批量删除对象
     *
     * @param ids
     * @return
     */
    @ResponseBody
    @RequestMapping("/delete")
    public Message<String> delete(String ids) {
        List<ID> idList = StringTools.split(ids, StringTools.VIRGULE, instanceAnnotationID());
        if (!idList.isEmpty()) {
            getBaseService().deleteByIdIn(idList);
            afterDelete(idList);
        }
        return Message.success("删除成功");
    }

    @ResponseBody
    @PostMapping("/delete/{id}")
    public Message<String> delete(@PathVariable ID id) {
        try {
            getBaseService().delete(id);
            afterDelete(Collections.singletonList(id));
        } catch (Exception e) {
            //如果id不在表中会抛异常
        }
        return Message.success("删除成功");
    }

    @ResponseBody
    @RequestMapping(value = "/page", produces = {"application/json;charset=UTF-8"})
    public PageMessage page(@RequestBody PagingRequest request) {
        request.searchhandler();
        proccessDate(request, "LT_createAt,GT_createAt,GTE_createAt,LTE_createAt");
        Page<T> pages = getBaseService().findPaging(request);
        PageMessage supplementResult = null;
        if (ObjectTools.isNotBlank(pages.getContent())) {
            supplementResult = supplement(pages.getContent());
        }
        if (supplementResult == null) {
            return request.toPageMessage(pages);
        } else {
            return supplementResult;
        }
    }

    public void proccessDate(PagingRequest request, String keys) {
        Map<String, Object> search = request.getSearch();
        if (!search.isEmpty()) {
            List<String> keyList = StringTools.split(keys, ",", String.class);
            for (String keyItem : keyList) {
                if (!search.containsKey(keyItem)) {
                    continue;
                }
                String valueData = (String) search.get(keyItem);
                if (StringTools.isNotBlank(valueData)) {
                    try {
                        LocalDateTime value = TimeFormat.toTime(valueData, TimeFormat.DATETIME);
                        search.put(keyItem, value);
                    } catch (Exception e) {
                        search.remove(keyItem);
                    }
                }
            }
        }
    }

    @ResponseBody
    @GetMapping(value = "/page/{page}/{limit}")
    public PageMessage page(@PathVariable(required = false) Integer page, @PathVariable(required = false) Integer limit, @RequestParam(required = false) String query, @RequestParam(required = false) String sort) {
        return page(new PagingRequest(page,limit,query,sort));
    }

    public PageMessage supplement(List<T> list) {
        return null;
    }

    protected Class<ID> instanceAnnotationID() {
        try {
            return GenericsTools.getSuperClassGenricType(this.getClass(), 1);
        } catch (Exception var2) {
            var2.printStackTrace();
            return null;
        }
    }

    public abstract BaseService<T, ID> getBaseService();
}
